package com.authentication.manager;

import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;

import java.util.Objects;

public class ClientAuthenticationManager implements AuthenticationManager {

    private final RegisteredClientRepository registeredClientRepository;

    public ClientAuthenticationManager(RegisteredClientRepository registeredClientRepository) {
        this.registeredClientRepository = registeredClientRepository;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

        if (authentication instanceof OAuth2ClientAuthenticationToken clientAuthentication) {

            RegisteredClient registeredClient = registeredClientRepository.findByClientId(clientAuthentication.getPrincipal().toString());

            if (registeredClient == null) {
                throw new AuthenticationCredentialsNotFoundException("未找到 clientId = " + clientAuthentication.getPrincipal() + " 的已注册client数据");
            }


            OAuth2ClientAuthenticationToken result = new OAuth2ClientAuthenticationToken(registeredClient, clientAuthentication.getClientAuthenticationMethod(), null);

            if (Objects.equals(registeredClient.getClientSecret(), authentication.getCredentials())) {
                result.setAuthenticated(true);
            }
            return result;
        }

        throw new InsufficientAuthenticationException("不支持对 OAuth2ClientAuthenticationToken 以外的 Authentication 进行认证");
    }
}
